package com.zf.nacos.config_change_refresh;

import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * RefreshScope注解刷新原理
 */
@RestController
@RequestMapping("/ccRefresh")
public class ConfigChangeRefreshController {
    @Autowired
    private UserInfoVO userInfoVO;

    @GetMapping("/userInfo")
    public String getUserInfo() {
        // 属性变更后，验证刷新后的对象是否变化
        System.out.println(userInfoVO.getInnerHash());
        System.out.println(userInfoVO.hashCode());

        return userInfoVO.toString();
    }

    /**
     * "@Value" 注入配置，默认先从 nacos 远程配置文件中拉取配置，找不到则再从本地获取配置；
     * 本地和远程都配置的情况下，优先使用远程配置
     * <p>
     * <pre>
     * RefreshScope注解: 当远程配置发生变动时，自动更新bean中注入的值:
     * 会对被标记的Bean创建代理对象，所有使用的地方都会使用该代理对象。
     * 每次刷新配置时，都会创建一个新的Bean，再将新的值刷入。但是代理对象不变，代理对象内部持有的Bean变成了新创建的Bean
     *      1、新增或者修改远程配置，会更新为远程配置的值
     *      2、远程配置被删除，但本地有配置，会更新为本地配置的值
     *      3、远程配置被删除，但本地没有配置：
     *           3.1、如果属性是基本数据类型，则无法创建新的bean,在使用时代理对象内部的Bean是NULL,会报错
     *           3.2、如果属性不是基本数据类型，会正常创建新的Bean,对应字段会设置为NULL,代理对象内部的Bean也会更新成新的Bean
     * </pre>
     */
    @RefreshScope
    @Component
    @Getter
    @Setter
    public static class UserInfoVO {

        @Value("${userInfo.name}")
        private String name;
        @Value("${userInfo.age}")
        private int age;

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

        /**
         * 内部对象的hash
         */
        public long getInnerHash() {
            return this.hashCode();
        }

    }

}
